﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Unity资源对象池，注意使用的是name作为key，所以放到里面的Prefab的Name不对冲突
/// </summary>
public class UnityPoolManager : MonoBehaviour {
	public static UnityPoolManager Instance;
	void Awake(){
		Instance = this;
	}

	/// <summary>
	/// 以名称作为key
	/// </summary>
	private Dictionary<string,List<Transform>> _pool = new Dictionary<string, List<Transform>>();

	#region gameObject
	/// <summary>
	/// 初始化一些空的GameObject
	/// </summary>
	/// <param name="size">Size.</param>
	public void InitGameObject(int size){
		string name = "GameObject";
		if(!_pool.ContainsKey(name)){
			_pool[name] = new List<Transform>();
		}
		else if(_pool[name].Count>=size){
			return;
		}
		for(int i = 0 ;i<size;++i){
			GameObject go = new GameObject(name);
			go.transform.SetParent(transform);
			go.SetActive(false);
			_pool[name].Add(go.transform);
		}
	}
	/// <summary>
	/// 获取GameObject
	/// </summary>
	/// <returns>The game object.</returns>
	public Transform GetGameObject(){
		string name = "GameObject";
		if(_pool.ContainsKey(name) && _pool[name].Count>0){
			Transform instance = _pool[name][0];
			_pool[name].RemoveAt(0);
			instance.gameObject.SetActive(true);
			return instance;
		}
		InitGameObject(5);
		return GetGameObject();
	}
	public void GameObjectBackToPool( Transform tran){
		string name = "GameObject";
		BackToPool(name,tran);
	}
	#endregion


	public void Init(Transform prefab,int size){
		string name = prefab.name;
		if(!_pool.ContainsKey(name)){
			_pool[name] = new List<Transform>();
		}
		else if(_pool[name].Count>=size){
			return;
		}
		for(int i = 0 ;i<size;++i){
			Transform instance = Instantiate(prefab) as Transform;
			instance.gameObject.SetActive(false);
			instance.gameObject.name = name;
			instance.transform.SetParent(transform);

			_pool[name].Add(instance.transform);
		}
	}
	public Transform Get(string name,Transform prefab){
		if(_pool.ContainsKey(name) && _pool[name].Count>0){
			Transform instance = _pool[name][0];
			_pool[name].RemoveAt(0);
			instance.gameObject.SetActive(true);
			return instance;
		}
		Init(prefab,5);
		return Get(prefab);
	}
	public Transform Get(Transform prefab){
		string name = prefab.name;
		if(_pool.ContainsKey(name) && _pool[name].Count>0){
			Transform instance = _pool[name][0];
			_pool[name].RemoveAt(0);
			instance.gameObject.SetActive(true);
			return instance;
		}
		Init(prefab,5);
		return Get(prefab);
	}

    public void BackToPool(Transform tan,float delay)
    {
        StartCoroutine(_Delay(tan,delay));
    }

    IEnumerator _Delay(Transform tan, float delay)
    {
        yield return new WaitForSeconds(delay);
        if (tan)
        {
            BackToPool(tan);
        }
    }

    public void BackToPool(Transform tran){
		string name = tran.name;
		tran.SetParent(transform) ;
		tran.gameObject.SetActive(false);
		tran.name = name;
		if(!_pool.ContainsKey(name)){
			_pool[name] = new List<Transform>();
		}
		if(!_pool[name].Contains(tran)){
			_pool[name].Add(tran);
		}
	}


	public void BackToPool(string name,Transform tran){
		tran.SetParent(transform) ;
		tran.gameObject.SetActive(false);
		tran.name = name;
		if(!_pool.ContainsKey(name)){
			_pool[name] = new List<Transform>();
		}
		if(!_pool[name].Contains(tran)){
			_pool[name].Add(tran);
		}
	}

	/// <summary>
	/// 将子节点全部返回到对象池中
	/// </summary>
	/// <param name="trans">Trans.</param>
	public void BackToPoolFromParent(Transform trans){
		var children = trans.GetComponentsInChildren<Transform>(true);
		for(int i  = 0;i<children.Length;++i){
			if(children[i]!=trans){
				BackToPool(children[i]);
			}
		}
	}

	void OnDestroy(){
		_pool.Clear();
		_pool = null;
	}
}
